﻿using System;
using System.Collections.Generic;
using System.Text;
using ContentRenderingApi.Skeleton;

namespace ContentRenderingApi.Data.Comparer
{
    /// <summary/>
    internal class SelfSortComparer : IComparer<AbstractData>
    {
        private SelfSortSkeleton _selfSortSkeleton;
        private SelfSortComparer _successor;

        /// <summary/>
        internal SelfSortComparer(SelfSortSkeleton selfSortSkeleton)
        {
            this._selfSortSkeleton = selfSortSkeleton;
        }

        /// <summary/>
        internal SelfSortComparer Successor
        {
            set { this._successor = value; }
        }

        /// <summary/>
        public int Compare(AbstractData dataOne, AbstractData dataTwo)
        {
            object valueOne = dataOne.RawValue;
            object valueTwo = dataTwo.RawValue;

            bool valueOneOk = this._selfSortSkeleton.Type.IsInstanceOfType(valueOne);
            bool valueTwoOk = this._selfSortSkeleton.Type.IsInstanceOfType(valueTwo);

            // how did the type comparison resolve?
            if (!valueOneOk && !valueTwoOk)
            {
                // the types are wrong so ask the successor to resolve it
                if (this._successor != null)
                {
                    return this._successor.Compare(dataOne, dataTwo);
                }

                return Constant.COMPARE_EQUAL;
            }
            else if (valueOneOk && !valueTwoOk)
            {
                return Constant.COMPARE_LEFT;
            }
            else if (!valueOneOk && valueTwoOk)
            {
                return Constant.COMPARE_RIGHT;
            }
            else
            {
                int result = this._selfSortSkeleton.Compare(valueOne, valueTwo);

                // if the values are NOT equal then we are done
                if (result != Constant.COMPARE_EQUAL)
                {
                    return result;
                }

                // was a successor provided ... if so use it to resolve the compare
                if (this._successor != null)
                {
                    return this._successor.Compare(dataOne, dataTwo);
                }

                // no successor ... so the values are equal
                return Constant.COMPARE_EQUAL;
            }
        }
    }
}
